home *** CD-ROM | disk | FTP | other *** search
- /* ==========================================================================
- **
- ** ListBrowser.c
- **
- ** ⌐1991 WILLISoft
- **
- ** ==========================================================================
- */
-
- #include <string.h>
- #include "minmax.h"
- #include "ListBrowser.h"
- #include "ListBrowserClass.h"
- #include "EmbossedGadgetClass.h"
- #include "precognition.h"
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include "amigamem.h"
-
- #define CHAR_WIDTH 8 /* Width of Topaz 80 font.*/
- #define CHAR_HEIGHT 9 /* Height of Topaz 80 font.*/
- #define BROWSER_ENTRY_HEIGHT (CHAR_HEIGHT + 1)
- #define BORDER_WIDTH 3
- #define BASELINE 8
-
- #define isSelected(q) (q & ENTRY_SELECTED)
-
- const StringList *ListBrowser_StringList_of( ListBrowser *self )
- {
- return &self->List;
- }
-
- void ListBrowser_Init( ListBrowser *self,
- PIXELS LeftEdge,
- PIXELS TopEdge,
- PIXELS Width,
- PIXELS Height,
- pcg_3DPens Pens,
- BOOL SelectMany )
- {
-
- EmbossedGadget_Init( &self->eg, LeftEdge, TopEdge, 0, 0,
- GADGHNONE, RELVERIFY, BOOLGADGET, Pens, NULL );
-
- self->eg.isa = ListBrowserClass();
- self->SelectMany = SelectMany;
- self->YOffset = 0;
- SetLocation( self, LeftEdge, TopEdge );
- SetSize( self, Width, Height );
-
- /* Initialize List structure... */
- StringList_Init( &self->List, TRUE );
-
- }
-
- void ListBrowser_CleanUp( ListBrowser *self )
- {
- StringList *sl;
-
- StringList_CleanUp( StringList_of(self) );
- EmbossedGadget_CleanUp( self );
- }
-
- Point ListBrowser_AskSize( ListBrowser *self,
- PIXELS Width,
- PIXELS Height )
- {
- Point size;
- short nCols, nRows;
-
- nCols = ( Width-BORDER_WIDTH*2 ) / CHAR_WIDTH;
- nRows = ( Height-BORDER_WIDTH*2 ) / BROWSER_ENTRY_HEIGHT;
-
- nCols = MAX( nCols, 5 );
- nRows = MAX( nRows, 5 );
-
- size.x = nCols*CHAR_WIDTH + BORDER_WIDTH*2;
- size.y = nRows*BROWSER_ENTRY_HEIGHT + BORDER_WIDTH*2;
-
- return size;
- }
-
-
- Point ListBrowser_SetSize( ListBrowser *self,
- PIXELS Width,
- PIXELS Height )
- {
- Point size;
-
- size = AskSize( self, Width, Height );
-
- Forbid(); /* Don't want Intuition looking at these while we modify em. */
- self->eg.Size = size;
- self->eg.g.Width = size.x - BORDER_WIDTH*2;
- self->eg.g.Height = size.y - BORDER_WIDTH*2;
-
- pcg_Init3DBox( self->eg.BoxBorder,
- -BORDER_WIDTH, -BORDER_WIDTH,
- size.x, size.y,
- self->eg.Pens.BrightPen, self->eg.Pens.DarkPen,
- self->eg.BoxBorder->BottomRight.NextBorder );
- Permit();
-
-
- self->nColumns = ( size.x-BORDER_WIDTH*2 ) / CHAR_WIDTH;
- self->nRows = ( size.y-BORDER_WIDTH*2 ) / BROWSER_ENTRY_HEIGHT;
-
- return size;
- }
-
- Point ListBrowser_SetLocation( ListBrowser *self,
- PIXELS LeftEdge,
- PIXELS TopEdge )
- {
- Point location;
-
- Forbid();
- self->eg.Location.x = LeftEdge;
- self->eg.Location.y = TopEdge;
- self->eg.g.LeftEdge = LeftEdge + BORDER_WIDTH;
- self->eg.g.TopEdge = TopEdge + BORDER_WIDTH;
- Permit();
-
-
- return location;
- }
-
- USHORT ListBrowser_SetYOffset( ListBrowser *self,
- USHORT YOffset )
- {
- SHORT MaxY;
-
- MaxY = MAX( self->List.nEntries-self->nRows, 0 );
- self->YOffset = MIN( YOffset, MaxY );
-
- return self->YOffset;
- }
-
-
-
- #define DESELECT_ALL(b) ListBrowser_SelectAll(b, FALSE)
-
- void ListBrowser_SelectAll( ListBrowser *self, BOOL Select )
- /* Selects or deselects everything in the list. */
- {
- USHORT i;
-
- for (i=0; i<self->List.nEntries; i++)
- {
- if (Select)
- self->List.Qualifiers[i] |= ENTRY_SELECTED;
- else
- self->List.Qualifiers[i] &= (UBYTE) ~ENTRY_SELECTED;
- }
-
- }
-
- void ListBrowser_SelectString( ListBrowser *self,
- USHORT i,
- BOOL Select )
- {
- if ((! self->SelectMany) && (Select))
- DESELECT_ALL( self );
-
- if (Select)
- self->List.Qualifiers[i] |= ENTRY_SELECTED;
- else
- self->List.Qualifiers[i] &= ~ENTRY_SELECTED;
- }
-
- void ListBrowser_DrawEntry( ListBrowser *self,
- RastPort *RPort,
- USHORT index )
- {
- USHORT count, X, Y, Xend, Yend;
- UBYTE qual, succ, pred;
- char **Entries;
- UBYTE *Qualifiers;
- pcg_3DPens pens;
-
- Entries = self->List.Entries;
- Qualifiers = self->List.Qualifiers;
-
- X = self->eg.Location.x + BORDER_WIDTH;
- Y = self->eg.Location.y + BORDER_WIDTH
- + (index-self->YOffset)*BROWSER_ENTRY_HEIGHT;
- Xend = X + self->eg.g.Width-1;
- Yend = Y + BROWSER_ENTRY_HEIGHT;
- pens = self->eg.Pens;
-
- SetDrMd( RPort, JAM1 );
- /* Clear the entry. */
- SetAPen( RPort, pens.BackPen );
- RectFill( RPort, X, Y, Xend, Yend );
-
-
- qual = Qualifiers[index];
- if (index)
- pred = Qualifiers[index-1];
- else
- pred = 0;
-
- if (index+1 < self->List.nEntries)
- succ = Qualifiers[index+1];
- else
- succ = 0;
-
-
- if (qual & ENTRY_SPECIAL)
- SetAPen( RPort, pens.FrontPen+1 );
- else
- SetAPen( RPort, pens.FrontPen );
-
- Move( RPort, X+1, Y+BASELINE );
- count = strlen( Entries[index] );
- count = MIN( self->nColumns, count );
- Text( RPort, Entries[index], count );
-
-
- if (isSelected(qual))
- {
- SetDrMd( RPort, COMPLEMENT );
-
- /* Draw 3D lines. */
- RectFill( RPort, X, Y, Xend, Yend );
- SetDrMd( RPort, JAM1 );
- SetAPen( RPort, pens.DarkPen );
- Move( RPort, X, Yend );
- Draw( RPort, X, Y );
-
- SetAPen( RPort, pens.BrightPen ); /* Right side bar. */
- Move( RPort, Xend, Y );
- Draw( RPort, Xend, Yend );
- }
-
- /* Draw top bar. */
- if (( (!isSelected(pred)) && isSelected(qual)))
- /* previous is not selected, entry is */
- {
- SetAPen( RPort, pens.DarkPen );
- Move( RPort, X, Y );
- Draw( RPort, Xend, Y );
- }
- else if (isSelected(pred) && (!isSelected(qual)))
- /* previous is selected, entry is not */
- {
- SetAPen( RPort, pens.BrightPen );
- Move( RPort, X, Y );
- Draw( RPort, Xend, Y );
- }
-
- /* Draw bottom bar */
- if ((!isSelected(succ)) && isSelected(qual))
- /* successor is not selected, entry is */
- {
- SetAPen( RPort, pens.BrightPen );
- Move( RPort, X, Yend );
- Draw( RPort, Xend, Yend );
- }
- else if (isSelected(succ) && (!isSelected(qual)))
- /* successor is selected, entry is not */
- {
- SetAPen( RPort, pens.DarkPen );
- Move( RPort, X, Yend );
- Draw( RPort, Xend, Yend );
- }
- }
-
-
- void ListBrowser_Render( ListBrowser *self,
- RastPort *RPort )
- {
- USHORT X, Y, Xend, Yend;
- USHORT i, j;
-
- X = self->eg.g.LeftEdge;/* + BORDER_WIDTH;*/
- Y = self->eg.g.TopEdge; /* + BORDER_WIDTH;*/
- Xend = X + self->eg.g.Width-1;
- Yend = Y + self->eg.g.Height-1;
-
-
- DrawBorder( RPort, self->eg.BoxBorder, self->eg.g.LeftEdge, self->eg.g.TopEdge );
-
- /* Clear the display area. */
- SetDrMd( RPort, JAM1 );
- SetAPen( RPort, self->eg.Pens.BackPen );
- RectFill( RPort, X, Y, Xend, Yend );
-
-
- /* Display the list */
- for( j=0, i=self->YOffset; j<self->nRows; j++, i++)
- {
- if (i>=self->List.nEntries) break;
- ListBrowser_DrawEntry( self, RPort, i );
- }
- }
-
-
- void ListBrowser_ChangeHighlight( ListBrowser *self,
- USHORT new_highlighted_entry, /* index */
- RastPort *RPort )
- {
- USHORT i, j;
- UBYTE *Qualifiers;
-
-
- /* Display the list */
- Qualifiers = self->List.Qualifiers;
-
- /* Deselect the old one. */
- i = self->YOffset;
- for (j=0; j<self->nRows; j++, i++)
- {
- if (i >= self->List.nEntries) break;
-
- if (isSelected(Qualifiers[i]) )
- {
- /* If this is the old highlight */
- Qualifiers[i] &= ~ENTRY_SELECTED;
- ListBrowser_DrawEntry( self, RPort, i );
- }
- }
-
- Qualifiers[new_highlighted_entry] |= ENTRY_SELECTED;
-
- if ((new_highlighted_entry - self->YOffset >= 0) &&
- (new_highlighted_entry - self->YOffset < self->nRows))
- ListBrowser_DrawEntry( self, RPort, new_highlighted_entry );
-
- }
-
-
- void ListBrowser_Refresh( ListBrowser *self )
- {
- struct pcgWindow *window;
-
- window = InteractorWindow( self );
- Render( self, window->Window->RPort );
- }
-
-
-
- void ListBrowser_AddString( ListBrowser *self,
- char *entry,
- UBYTE qualifier )
- {
- if ((! self->SelectMany) && isSelected(qualifier))
- DESELECT_ALL( self );
- /* This new entry is selected, so all others must be deselected. */
-
- StringList_AddString( &self->List, entry, qualifier );
- }
-
-
- BOOL ListBrowser_DeleteString( ListBrowser *self, USHORT i )
- {
- BOOL result;
- StringList *sl;
-
- /*DUMPWAIT("ListBrowser_DeleteString\n");*/
-
- sl = StringList_of(self);
-
- result = StringList_DeleteString( sl, i );
-
- ListBrowser_SetYOffset( self, self->YOffset );
-
- /*DUMPWAIT("end ListBrowser_DeleteString\n");*/
-
- return result;
-
- }
-
- BOOL ListBrowser_DeleteAllStrings( ListBrowser *self )
- {
- BOOL result;
-
- result = StringList_DeleteAllStrings( &self->List );
- ListBrowser_SetYOffset( self, self->YOffset );
-
- return result;
- }
-
-
-
- #define CLAIM_EVENT(b,e) (&b->eg.g == (Gadget *) e->IAddress)
-
- USHORT ListBrowser_Respond( ListBrowser *self,
- IntuiMessage *Event )
- {
- Point Mouse;
- USHORT entry_no;
- USHORT response = 0;
- UBYTE qual;
-
- switch (Event->Class)
- {
- case REFRESHWINDOW:
- ListBrowser_Render( self, Event->IDCMPWindow->RPort );
- response = RESPONDED;
- break;
-
- case GADGETUP:
- if (CLAIM_EVENT(self, Event))
- {
- /* Translate into Gadget-Relative Coordinates. */
- GadgetRelativeCoords( &self->eg.g, Event, &Mouse );
- entry_no = (Mouse.y - BORDER_WIDTH) / BROWSER_ENTRY_HEIGHT
- + self->YOffset;
- entry_no = MAX( entry_no, 0 );
-
- qual = self->List.Qualifiers[entry_no];
-
- if ( entry_no < self->List.nEntries )
- {
- if (self->SelectMany)
- {
- SelectString( self, entry_no, !isSelected(qual) );
- ListBrowser_DrawEntry( self,
- Event->IDCMPWindow->RPort, entry_no );
- }
- else
- {
- if (!isSelected(qual)) /* Only select if not already. */
- { /* (Avoids ugly screen update.) */
- ListBrowser_ChangeHighlight( self, entry_no,
- Event->IDCMPWindow->RPort );
- }
- }
- }
- response = RESPONDED | CHANGED_STATE | CONSUMED_EVENT;
- }
- break;
-
- }
- return response;
- }
-
-
-
- BOOL ListBrowser_elaborated = FALSE;
-
- struct StringListerClass ListBrowser_Class;
-
- void ListBrowserClass_Init( struct StringListerClass *class )
- {
-
- StringListerClass_Init( class );
- EmbossedGadgetClass_Init( class );
- class->isa = StringListerClass();
- class->ClassName = "ListBrowser";
- class->CleanUp = ListBrowser_CleanUp;
- class->AskSize = ListBrowser_AskSize;
- class->SetSize = ListBrowser_SetSize;
- class->SizeFlags = GraphicObject_SizeFlagsAll;
- class->SetLocation = ListBrowser_SetLocation;
- class->Respond = ListBrowser_Respond;
- class->Render = ListBrowser_Render;
- class->Refresh = ListBrowser_Refresh;
-
- class->AddString = ListBrowser_AddString;
- class->DeleteString = ListBrowser_DeleteString;
- class->DeleteAllStrings = ListBrowser_DeleteAllStrings;
- class->StringList_of = ListBrowser_StringList_of;
- class->SelectString = ListBrowser_SelectString;
- }
-
-
- struct StringListerClass *ListBrowserClass( void )
- {
- if (! ListBrowser_elaborated)
- {
- ListBrowserClass_Init( &ListBrowser_Class );
- ListBrowser_elaborated = TRUE;
- }
-
- return &ListBrowser_Class;
- }
-